#include "solution.h"
#include "main-tools.h"

Psolution initSolution(int* K, int* N){
	Psolution result = (Psolution)malloc(sizeof(Solution));
	checkMalloc(result,"solution.c:initSolution#1");
	result->K = K;
	result->states = (PvehicleState*)malloc(*K*sizeof(PvehicleState));
	checkMalloc(result->states,"solution.c:initSolution:2");
	int i;
	for(i=0; i<*K; i++)
		result->states[i] = initVehicleState();
		
	result->gMatrix = initGMatrix(N, NOT_GATHERED);
	return result;
}

PvehiclePath getVehiclePathInSolution(Psolution ps, int k){
	return (ps->states[k]->pvp);
}

PvehicleState getVehicleStateInSolution(Psolution ps, int k){
	return ps->states[k];
}

int getSolutionProfit(Psolution ps){
	int k;
	int somma = 0;
	for (k=0; k<*ps->K; k++){
		somma += ps->states[k]->jk;
	}
	return somma;
}

int getSolutionTimeCost(Psolution ps){
	int k;
	int somma=0;
	for (k=0;k<*ps->K;k++){
		somma += ps->states[k]->tau;
	}
	return somma;
}

int getSolutionLoadCost(Psolution ps){
	int k;
	int somma=0;
	for (k=0;k<*ps->K;k++){
		somma += ps->states[k]->theta;
	}
	return somma;
}

void printSolutionProfit(FILE* f, Psolution ps){
	fprintf(f, "Il profitto totale della soluzione vale %d.\n", getSolutionProfit(ps));
}


void printSolutionTimeCost(FILE* f, Psolution ps){
	fprintf(f, "Il costo temporale totale della soluzione vale %d.\n",getSolutionTimeCost(ps));
}

void printSolutionLoadCost(FILE* f, Psolution ps){
	fprintf(f, "Il carico totale della soluzione vale %d.\n",getSolutionLoadCost(ps));
}

//TODO testing
Psolution cloneSolution(Psolution solution){
	int i;
	Psolution result=(Psolution)malloc(sizeof(Solution));
	checkMalloc(result,"solution.c:cloneSolution:1");
	result->K=solution->K;
	result->gMatrix=cloneGMatrix(solution->gMatrix);
	result->states = (PvehicleState*)malloc(*solution->K*sizeof(PvehicleState));
	checkMalloc(result->states,"solution.c:cloneSolution:2");
	for (i=0;i<*solution->K;i++){
		result->states[i]=cloneVehicleState(solution->states[i]);
	}
	return result;
}
//TODO testing
void freeSolution(Psolution psolution){
	int i;
	//dealloco la matrice G
	freeGMatrix(psolution->gMatrix);
	//dealloco le singole istanze dei VehicleState
	for (i=0;i<*psolution->K;i++){
		freeVehicleState(psolution->states[i]);
	}
	//dealloco l'array contenente i puntatori di VehicleStates
	free(psolution->states);
	//dealloco la struttura psolution
	free(psolution);
}

void printSolution(FILE* f, Psolution ps) {
	fprintf(f, "-----------------------------------------------\n");
	int i;
	for (i=0; i<*ps->K; i++){
		printVehicleState(f, ps->states[i], i);
		fprintf(f, "\n");
	}
	printGMatrix(f, ps->gMatrix);
	fprintf(f, "\n-----------------------------------------------\n");
}

void printVehicles(FILE* f, Psolution ps) {
	fprintf(f, "-----------------------------------------------\n");
	int i;
	for (i=0; i<*ps->K; i++){
		printVehicleState(f, ps->states[i], i);
		printVehicleGathering(f, getVehiclePathInSolution(ps,i), ps->gMatrix, i);
		fprintf(f, "\n");
	}
	fprintf(f, "-----------------------------------------------\n");
}

void printVehicleGathering(FILE* f, PvehiclePath pvp, PGMatrix pgm, int k) {
	PvehiclePath it = pvp->next;
	fprintf(f,"Raccolta:\n{");
	while (it->edge!=NULL){
		if(amIGatheringEdge(pgm, it->edge->id, k)) {
			printEdgeID(f, it->edge->id);
			fprintf(f, "\t");
		}

		it = it->next;
	}
	fprintf(f,"}\n");
}
